package com.unswift.cloud.filter;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;

import com.unswift.annotation.api.Api;
import com.unswift.annotation.api.ApiField;
import com.unswift.annotation.api.ApiMethod;
import com.unswift.cloud.config.TokenConfig;
import com.unswift.cloud.pojo.vo.BaseVo;
import com.unswift.cloud.pojo.vo.ResponseBody;
import com.unswift.utils.ExceptionUtils;
import com.unswift.utils.JsonUtils;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Api(value="微服务拦截器抽象类，一些公告的操作", author = "unswift", date = "2023-08-13", version = "1.0.0")
public abstract class CloudFilter {

	@ApiField("日志对象")
	protected final Logger logger=LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	@ApiField("token的yml配置")
	protected TokenConfig tokenConfig;
	
	@ApiMethod(value="gateway根据请求获取body内容", params = @ApiField("gateway的request对象"), returns = @ApiField("body内容"))
	protected String getRequstBody(ServerHttpRequest request) {
		AtomicReference<String> bodyRef = new AtomicReference<>();
		Flux<DataBuffer> body = request.getBody();
		body.subscribe(dataBuffer -> {
            byte[] bytes = new byte[dataBuffer.readableByteCount()];
            dataBuffer.read(bytes);
            DataBufferUtils.release(dataBuffer);
            String content = new String(bytes, StandardCharsets.UTF_8);
			bodyRef.set(content);
        });
		return bodyRef.get();
    }
	
	@ApiMethod(value="gateway根据请求获取body内容", params = @ApiField("gateway的request对象"), returns = @ApiField("body内容"))
	protected byte[] getRequstByteBody(ServerHttpRequest request) {
		ByteArrayOutputStream bodyRef=new ByteArrayOutputStream();
		Flux<DataBuffer> body = request.getBody();
		body.subscribe(dataBuffer -> {
            byte[] bytes = new byte[dataBuffer.readableByteCount()];
            dataBuffer.read(bytes);
            DataBufferUtils.release(dataBuffer);
            try {
				bodyRef.write(bytes);
			} catch (IOException e) {
				e.printStackTrace();
				logger.error(e.getMessage(), e);
			}
        });
		return bodyRef.toByteArray();
    }
	
	@ApiMethod(value="根据json对象返回", params = {@ApiField("gateway拦截器请求对象"), @ApiField("返回body对象")}, returns = @ApiField("gateway拦截器返回对象"))
	protected Mono<Void> toJson(ServerWebExchange exchange, ResponseBody<BaseVo> responseBody) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.OK);
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        byte[] datas = JsonUtils.toJson(responseBody).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(datas);
        return response.writeWith(Mono.just(buffer));
    }
	
	@ApiMethod(value="根据请求path获取路由，如：/login/logging会返回/login", params = @ApiField("请求path"), returns = @ApiField("路由"))
	protected String getRequestRoute(String path) {
		int first=path.indexOf("/");
		int last=path.indexOf("/", first+1);
		if(last!=-1) {
			return path.substring(first, last);
		}
		return null;
	}
	
	@ApiMethod(value="根据header token获取用户token", params = {@ApiField("Request Headers Token")})
	protected String getUserToken(String token) {
		String prefix = tokenConfig.getHeader()+" ";
		ExceptionUtils.falseException(token.startsWith(prefix), "token.format.error");//Request Token必须以指定字符开始
		return token.substring(prefix.length());
	}
}
